package com.drakulo.games.ais.ui.component;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;

/**
 * A simple interface for all UI components
 * 
 * @author Drakulo
 * 
 */
public abstract class UIComponent {
	/** Display flag */
	protected boolean shown;
	/** Hover flag */
	protected boolean hovered;
	/** X coordinate */
	protected int ox;
	/** Y coordinate */
	protected int oy;
	/** The component width */
	protected int width;
	/** The component height */
	protected int height;
	/** The component zone */
	protected Rectangle zone;

	/**
	 * Render the component
	 */
	public abstract void render(Graphics g) throws SlickException;

	/**
	 * Perform an update
	 */
	public abstract void update(Input input) throws SlickException;

	/**
	 * Show the menu
	 */
	public void show() {
		this.shown = true;
		if (this instanceof Bindable) {
			Bindable b = (Bindable) this;
			if (b.getBindable() != null) {
				b.getBindable().setVisible(true);
			}
		}
	}

	/**
	 * Hide the menu
	 */
	public void hide() {
		this.shown = false;
		if (this instanceof Bindable) {
			Bindable b = (Bindable) this;
			if (b.getBindable() != null) {
				b.getBindable().setVisible(false);
			}
		}
	}

	/**
	 * @return true if the menu is shown
	 */
	public boolean isShown() {
		return this.shown;
	}

	public int getOX() {
		return this.ox;
	}

	public void setOX(int ox) {
		this.ox = ox;
		updateZone();
	}

	public int getOY() {
		return this.oy;
	}

	public void setOY(int oy) {
		this.oy = oy;
		updateZone();
	}

	public int getWidth() {
		return this.width;
	}

	public void setWidth(int width) {
		this.width = width;
		updateZone();
		if (this instanceof Bindable) {
			Bindable b = (Bindable) this;
			if (b.getBindable() != null) {
				b.getBindable().setSize(width, b.getBindable().getHeight());
			}
		}
	}

	public int getHeight() {
		return this.height;
	}

	public void setHeight(int height) {
		this.height = height;
		updateZone();
		if (this instanceof Bindable) {
			Bindable b = (Bindable) this;
			if (b.getBindable() != null) {
				b.getBindable().setSize(b.getBindable().getWidth(), height);
			}
		}
	}

	private void updateZone() {
		this.zone = new Rectangle(this.ox, this.oy, this.width, this.height);
	}

	/**
	 * 
	 * @param mx
	 *            mouse X position
	 * @param my
	 *            mouse Y position
	 * @return true if the mouse position is in the rectangle
	 */
	protected void updateHovered(int mx, int my) {
		this.hovered = this.zone.contains(mx, my);
	}

	public boolean isHovered() {
		return this.hovered;
	}

	public void setHovered(boolean hovered) {
		this.hovered = hovered;
	}

	/**
	 * Toggle the display of this component. If it is shown, then it is hidden
	 * and vice versa.
	 */
	public void toggleDisplay() {
		shown = !shown;
	}
}
